<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <p id="p"></p>
    <button id="btn">修改</button>
    <button id="dele">删除</button>
    <script>
      let p = document.getElementById("p");
      let btn = document.getElementById("btn");
      let dele = document.getElementById("dele");
      let user = {
        uname: "小明",
        uother: {
          aaa: 100,
          test: {
            m: 200,
          },
        },
      };
      p.innerText = JSON.stringify(user);
      // 通过Proxy代理user对象，这个代理对象可以实现源对象属性的增删响应。
      /*
      let proxy = new Proxy(user, {
        set(origin, key, value) {
          origin[key] = value;
          // console.log("--set", origin);
          p.innerText = JSON.stringify(user);
        },
        get(origin, key) {
          // console.log("--get", origin);
          return origin[key];
        },
        deleteProperty(origin, key) {
          delete origin[key];
          // console.log("--delete", origin);
          p.innerText = JSON.stringify(user);
        },
      });
      console.log(proxy);
      */

      // 通过递归实现对象的深度转化，将每一层都转化为Proxy代理对象。
      function reacitve(target, proxyObj = null, key = "") {
        let proxy = new Proxy(target, {
          set(origin, key, value) {
            origin[key] = value;
          },
          get(origin, key) {
            return origin[key];
          },
          defineProperty(origin, key) {
            delete origin[key];
          },
        });
        if (key) proxyObj[key] = proxy;
        for (const key in proxy) {
          const value = proxy[key];
          if (typeof value == "object") {
            reacitve(value, proxy, key);
          }
        }
        return proxy;
      }

      let userProxy = reacitve(user);
      console.log("---", userProxy);

      btn.onclick = () => {
        // proxy.uname = "1213";
        // console.log(proxy.uname);
        // proxy.a = 100;
        proxy.uother.aaa++;
      };
      dele.onclick = () => {
        delete proxy.uname;
      };
    </script>
  </body>
</html>
